home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / memory.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  59KB  |  1,871 lines

  1. /***************************************************************************
  2.  
  3.   memory.c
  4.  
  5.   Functions which handle the CPU memory and I/O port access.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "osd_cpu.h"
  11.  
  12. /* #define MEM_DUMP */
  13.  
  14. #ifdef MEM_DUMP
  15. static void mem_dump( void );
  16. #endif
  17.  
  18. /* Convenience macros - not in cpuintrf.h because they shouldn't be used by everyone */
  19. #define ADDRESS_BITS(index)             (cpuintf[Machine->drv->cpu[index].cpu_type & ~CPU_FLAGS_MASK].address_bits)
  20. #define ABITS1(index)                    (cpuintf[Machine->drv->cpu[index].cpu_type & ~CPU_FLAGS_MASK].abits1)
  21. #define ABITS2(index)                    (cpuintf[Machine->drv->cpu[index].cpu_type & ~CPU_FLAGS_MASK].abits2)
  22. #define ABITS3(index)                    (0)
  23. #define ABITSMIN(index)                 (cpuintf[Machine->drv->cpu[index].cpu_type & ~CPU_FLAGS_MASK].abitsmin)
  24.  
  25. #if LSB_FIRST
  26.     #define BYTE_XOR_BE(a) ((a) ^ 1)
  27.     #define BYTE_XOR_LE(a) (a)
  28. #else
  29.     #define BYTE_XOR_BE(a) (a)
  30.     #define BYTE_XOR_LE(a) ((a) ^ 1)
  31. #endif
  32.  
  33. unsigned char *OP_RAM;
  34. unsigned char *OP_ROM;
  35.  
  36. /* change bases preserving opcode/data shift for encrypted games */
  37. #define SET_OP_RAMROM(base)                 \
  38.     OP_ROM = (base) + (OP_ROM - OP_RAM);    \
  39.     OP_RAM = (base);
  40.  
  41.  
  42. MHELE ophw;             /* op-code hardware number */
  43.  
  44. struct ExtMemory ext_memory[MAX_EXT_MEMORY];
  45.  
  46. static unsigned char *ramptr[MAX_CPU],*romptr[MAX_CPU];
  47.  
  48. /* element shift bits, mask bits */
  49. int mhshift[MAX_CPU][3], mhmask[MAX_CPU][3];
  50.  
  51. /* pointers to port structs */
  52. /* ASG: port speedup */
  53. static struct IOReadPort *readport[MAX_CPU];
  54. static struct IOWritePort *writeport[MAX_CPU];
  55. static int portmask[MAX_CPU];
  56. static int readport_size[MAX_CPU];
  57. static int writeport_size[MAX_CPU];
  58. /* HJB 990210: removed 'static' for access by assembly CPU core memory handlers */
  59. const struct IOReadPort *cur_readport;
  60. const struct IOWritePort *cur_writeport;
  61. int cur_portmask;
  62.  
  63. /* current hardware element map */
  64. static MHELE *cur_mr_element[MAX_CPU];
  65. static MHELE *cur_mw_element[MAX_CPU];
  66.  
  67. /* sub memory/port hardware element map */
  68. /* HJB 990210: removed 'static' for access by assembly CPU core memory handlers */
  69. MHELE readhardware[MH_ELEMAX << MH_SBITS];    /* mem/port read  */
  70. MHELE writehardware[MH_ELEMAX << MH_SBITS]; /* mem/port write */
  71.  
  72. /* memory hardware element map */
  73. /* value:                       */
  74. #define HT_RAM      0     /* RAM direct         */
  75. #define HT_BANK1  1     /* bank memory #1     */
  76. #define HT_BANK2  2     /* bank memory #2     */
  77. #define HT_BANK3  3     /* bank memory #3     */
  78. #define HT_BANK4  4     /* bank memory #4     */
  79. #define HT_BANK5  5     /* bank memory #5     */
  80. #define HT_BANK6  6     /* bank memory #6     */
  81. #define HT_BANK7  7     /* bank memory #7     */
  82. #define HT_BANK8  8     /* bank memory #8     */
  83. #define HT_BANK9  9     /* bank memory #9     */
  84. #define HT_BANK10 10    /* bank memory #10     */
  85. #define HT_BANK11 11    /* bank memory #11     */
  86. #define HT_BANK12 12    /* bank memory #12     */
  87. #define HT_BANK13 13    /* bank memory #13     */
  88. #define HT_BANK14 14    /* bank memory #14     */
  89. #define HT_BANK15 15    /* bank memory #15     */
  90. #define HT_BANK16 16    /* bank memory #16     */
  91. #define HT_NON      17    /* non mapped memory */
  92. #define HT_NOP      18    /* NOP memory         */
  93. #define HT_RAMROM 19    /* RAM ROM memory     */
  94. #define HT_ROM      20    /* ROM memory         */
  95.  
  96. #define HT_USER   21    /* user functions     */
  97. /* [MH_HARDMAX]-0xff      link to sub memory element  */
  98. /*                          (value-MH_HARDMAX)<<MH_SBITS -> element bank */
  99.  
  100. #define HT_BANKMAX (HT_BANK1 + MAX_BANKS - 1)
  101.  
  102. /* memory hardware handler */
  103. /* HJB 990210: removed 'static' for access by assembly CPU core memory handlers */
  104. mem_read_handler memoryreadhandler[MH_HARDMAX];
  105. int memoryreadoffset[MH_HARDMAX];
  106. mem_write_handler memorywritehandler[MH_HARDMAX];
  107. int memorywriteoffset[MH_HARDMAX];
  108.  
  109. /* bank ram base address; RAM is bank 0 */
  110. unsigned char *cpu_bankbase[HT_BANKMAX + 1];
  111. static int bankreadoffset[HT_BANKMAX + 1];
  112. static int bankwriteoffset[HT_BANKMAX + 1];
  113.  
  114. /* override OP base handler */
  115. static opbase_handler setOPbasefunc[MAX_CPU];
  116. static opbase_handler OPbasefunc;
  117.  
  118. /* current cpu current hardware element map point */
  119. MHELE *cur_mrhard;
  120. MHELE *cur_mwhard;
  121.  
  122. /* empty port handler structures */
  123. static struct IOReadPort empty_readport[] =
  124. {
  125.     { -1 }
  126. };
  127.  
  128. static struct IOWritePort empty_writeport[] =
  129. {
  130.     { -1 }
  131. };
  132.  
  133. static void *install_port_read_handler_common(int cpu, int start, int end, mem_read_handler handler, int install_at_beginning);
  134. static void *install_port_write_handler_common(int cpu, int start, int end, mem_write_handler handler, int install_at_beginning);
  135.  
  136.  
  137. /***************************************************************************
  138.  
  139.   Memory read handling
  140.  
  141. ***************************************************************************/
  142.  
  143. READ_HANDLER(mrh_ram)        { return cpu_bankbase[0][offset]; }
  144. READ_HANDLER(mrh_bank1)     { return cpu_bankbase[1][offset]; }
  145. READ_HANDLER(mrh_bank2)     { return cpu_bankbase[2][offset]; }
  146. READ_HANDLER(mrh_bank3)     { return cpu_bankbase[3][offset]; }
  147. READ_HANDLER(mrh_bank4)     { return cpu_bankbase[4][offset]; }
  148. READ_HANDLER(mrh_bank5)     { return cpu_bankbase[5][offset]; }
  149. READ_HANDLER(mrh_bank6)     { return cpu_bankbase[6][offset]; }
  150. READ_HANDLER(mrh_bank7)     { return cpu_bankbase[7][offset]; }
  151. READ_HANDLER(mrh_bank8)     { return cpu_bankbase[8][offset]; }
  152. READ_HANDLER(mrh_bank9)     { return cpu_bankbase[9][offset]; }
  153. READ_HANDLER(mrh_bank10)    { return cpu_bankbase[10][offset]; }
  154. READ_HANDLER(mrh_bank11)    { return cpu_bankbase[11][offset]; }
  155. READ_HANDLER(mrh_bank12)    { return cpu_bankbase[12][offset]; }
  156. READ_HANDLER(mrh_bank13)    { return cpu_bankbase[13][offset]; }
  157. READ_HANDLER(mrh_bank14)    { return cpu_bankbase[14][offset]; }
  158. READ_HANDLER(mrh_bank15)    { return cpu_bankbase[15][offset]; }
  159. READ_HANDLER(mrh_bank16)    { return cpu_bankbase[16][offset]; }
  160. static mem_read_handler bank_read_handler[] =
  161. {
  162.     mrh_ram,   mrh_bank1,  mrh_bank2,  mrh_bank3,  mrh_bank4,  mrh_bank5,  mrh_bank6,  mrh_bank7,
  163.     mrh_bank8, mrh_bank9,  mrh_bank10, mrh_bank11, mrh_bank12, mrh_bank13, mrh_bank14, mrh_bank15,
  164.     mrh_bank16
  165. };
  166.  
  167. READ_HANDLER(mrh_error)
  168. {
  169.     logerror("CPU #%d PC %04x: warning - read %02x from unmapped memory address %04x\n",cpu_getactivecpu(),cpu_get_pc(),cpu_bankbase[0][offset],offset);
  170.     return cpu_bankbase[0][offset];
  171. }
  172.  
  173. READ_HANDLER(mrh_error_sparse)
  174. {
  175.     logerror("CPU #%d PC %08x: warning - read unmapped memory address %08x\n",cpu_getactivecpu(),cpu_get_pc(),offset);
  176.     return 0;
  177. }
  178.  
  179. READ_HANDLER(mrh_error_sparse_bit)
  180. {
  181.     logerror("CPU #%d PC %08x: warning - read unmapped memory bit addr %08x (byte addr %08x)\n",cpu_getactivecpu(),cpu_get_pc(),offset<<3, offset);
  182.     return 0;
  183. }
  184.  
  185. READ_HANDLER(mrh_nop)
  186. {
  187.     return 0;
  188. }
  189.  
  190.  
  191. /***************************************************************************
  192.  
  193.   Memory write handling
  194.  
  195. ***************************************************************************/
  196.  
  197. WRITE_HANDLER(mwh_ram)        { cpu_bankbase[0][offset] = data;}
  198. WRITE_HANDLER(mwh_bank1)    { cpu_bankbase[1][offset] = data; }
  199. WRITE_HANDLER(mwh_bank2)    { cpu_bankbase[2][offset] = data; }
  200. WRITE_HANDLER(mwh_bank3)    { cpu_bankbase[3][offset] = data; }
  201. WRITE_HANDLER(mwh_bank4)    { cpu_bankbase[4][offset] = data; }
  202. WRITE_HANDLER(mwh_bank5)    { cpu_bankbase[5][offset] = data; }
  203. WRITE_HANDLER(mwh_bank6)    { cpu_bankbase[6][offset] = data; }
  204. WRITE_HANDLER(mwh_bank7)    { cpu_bankbase[7][offset] = data; }
  205. WRITE_HANDLER(mwh_bank8)    { cpu_bankbase[8][offset] = data; }
  206. WRITE_HANDLER(mwh_bank9)    { cpu_bankbase[9][offset] = data; }
  207. WRITE_HANDLER(mwh_bank10)    { cpu_bankbase[10][offset] = data; }
  208. WRITE_HANDLER(mwh_bank11)    { cpu_bankbase[11][offset] = data; }
  209. WRITE_HANDLER(mwh_bank12)    { cpu_bankbase[12][offset] = data; }
  210. WRITE_HANDLER(mwh_bank13)    { cpu_bankbase[13][offset] = data; }
  211. WRITE_HANDLER(mwh_bank14)    { cpu_bankbase[14][offset] = data; }
  212. WRITE_HANDLER(mwh_bank15)    { cpu_bankbase[15][offset] = data; }
  213. WRITE_HANDLER(mwh_bank16)    { cpu_bankbase[16][offset] = data; }
  214. static mem_write_handler bank_write_handler[] =
  215. {
  216.     mwh_ram,   mwh_bank1,  mwh_bank2,  mwh_bank3,  mwh_bank4,  mwh_bank5,  mwh_bank6,  mwh_bank7,
  217.     mwh_bank8, mwh_bank9,  mwh_bank10, mwh_bank11, mwh_bank12, mwh_bank13, mwh_bank14, mwh_bank15,
  218.     mwh_bank16
  219. };
  220.  
  221. WRITE_HANDLER(mwh_error)
  222. {
  223.     logerror("CPU #%d PC %04x: warning - write %02x to unmapped memory address %04x\n",cpu_getactivecpu(),cpu_get_pc(),data,offset);
  224.     cpu_bankbase[0][offset] = data;
  225. }
  226.  
  227. WRITE_HANDLER(mwh_error_sparse)
  228. {
  229.     logerror("CPU #%d PC %08x: warning - write %02x to unmapped memory address %08x\n",cpu_getactivecpu(),cpu_get_pc(),data,offset);
  230. }
  231.  
  232. WRITE_HANDLER(mwh_error_sparse_bit)
  233. {
  234.     logerror("CPU #%d PC %08x: warning - write %02x to unmapped memory bit addr %08x\n",cpu_getactivecpu(),cpu_get_pc(),data,offset<<3);
  235. }
  236.  
  237. WRITE_HANDLER(mwh_rom)
  238. {
  239.     logerror("CPU #%d PC %04x: warning - write %02x to ROM address %04x\n",cpu_getactivecpu(),cpu_get_pc(),data,offset);
  240. }
  241.  
  242. WRITE_HANDLER(mwh_ramrom)
  243. {
  244.     cpu_bankbase[0][offset] = cpu_bankbase[0][offset + (OP_ROM - OP_RAM)] = data;
  245. }
  246.  
  247. WRITE_HANDLER(mwh_nop)
  248. {
  249. }
  250.  
  251.  
  252. /***************************************************************************
  253.  
  254.   Memory structure building
  255.  
  256. ***************************************************************************/
  257.  
  258. /* return element offset */
  259. static MHELE *get_element( MHELE *element , int ad , int elemask ,
  260.                         MHELE *subelement , int *ele_max )
  261. {
  262.     MHELE hw = element[ad];
  263.     int i,ele;
  264.     int banks = ( elemask / (1<<MH_SBITS) ) + 1;
  265.  
  266.     if( hw >= MH_HARDMAX ) return &subelement[(hw-MH_HARDMAX)<<MH_SBITS];
  267.  
  268.     /* create new element block */
  269.     if( (*ele_max)+banks > MH_ELEMAX )
  270.     {
  271.         logerror("memory element size over \n");
  272.         return 0;
  273.     }
  274.     /* get new element nunber */
  275.     ele = *ele_max;
  276.     (*ele_max)+=banks;
  277. #ifdef MEM_DUMP
  278.     logerror("create element %2d(%2d)\n",ele,banks);
  279. #endif
  280.     /* set link mark to current element */
  281.     element[ad] = ele + MH_HARDMAX;
  282.     /* get next subelement top */
  283.     subelement    = &subelement[ele<<MH_SBITS];
  284.     /* initialize new block */
  285.     for( i = 0 ; i < (1<<MH_SBITS) ; i++ )
  286.         subelement[i] = hw;
  287.  
  288.     return subelement;
  289. }
  290.  
  291. static void set_element( int cpu , MHELE *celement , int sp , int ep , MHELE type , MHELE *subelement , int *ele_max )
  292. {
  293.     int i;
  294.     int edepth = 0;
  295.     int shift,mask;
  296.     MHELE *eele = celement;
  297.     MHELE *sele = celement;
  298.     MHELE *ele;
  299.     int ss,sb,eb,ee;
  300.  
  301. #ifdef MEM_DUMP
  302.     logerror("set_element %8X-%8X = %2X\n",sp,ep,type);
  303. #endif
  304.     if( (unsigned int) sp > (unsigned int) ep ) return;
  305.     do{
  306.         mask  = mhmask[cpu][edepth];
  307.         shift = mhshift[cpu][edepth];
  308.  
  309.         /* center element */
  310.         ss = (unsigned int) sp >> shift;
  311.         sb = (unsigned int) sp ? ((unsigned int) (sp-1) >> shift) + 1 : 0;
  312.         eb = ((unsigned int) (ep+1) >> shift) - 1;
  313.         ee = (unsigned int) ep >> shift;
  314.  
  315.         if( sb <= eb )
  316.         {
  317.             if( (sb|mask)==(eb|mask) )
  318.             {
  319.                 /* same reasion */
  320.                 ele = (sele ? sele : eele);
  321.                 for( i = sb ; i <= eb ; i++ ){
  322.                     ele[i & mask] = type;
  323.                 }
  324.             }
  325.             else
  326.             {
  327.                 if( sele ) for( i = sb ; i <= (sb|mask) ; i++ )
  328.                     sele[i & mask] = type;
  329.                 if( eele ) for( i = eb&(~mask) ; i <= eb ; i++ )
  330.                     eele[i & mask] = type;
  331.             }
  332.         }
  333.  
  334.         edepth++;
  335.  
  336.         if( ss == sb ) sele = 0;
  337.         else sele = get_element( sele , ss & mask , mhmask[cpu][edepth] ,
  338.                                     subelement , ele_max );
  339.         if( ee == eb ) eele = 0;
  340.         else eele = get_element( eele , ee & mask , mhmask[cpu][edepth] ,
  341.                                     subelement , ele_max );
  342.  
  343.     }while( sele || eele );
  344. }
  345.  
  346.  
  347. /* ASG 980121 -- allocate all the external memory */
  348. static int memory_allocate_ext (void)
  349. {
  350.     struct ExtMemory *ext = ext_memory;
  351.     int cpu;
  352.  
  353.     /* a change for MESS */
  354.     if (Machine->gamedrv->rom == 0)  return 1;
  355.  
  356.     /* loop over all CPUs */
  357.     for (cpu = 0; cpu < cpu_gettotalcpu (); cpu++)
  358.     {
  359.         const struct MemoryReadAddress *mra;
  360.         const struct MemoryWriteAddress *mwa;
  361.  
  362.         int region = REGION_CPU1+cpu;
  363.         int size = memory_region_length(region);
  364.  
  365.         /* now it's time to loop */
  366.         while (1)
  367.         {
  368.             int lowest = 0x7fffffff, end, lastend;
  369.  
  370.             /* find the base of the lowest memory region that extends past the end */
  371.             for (mra = Machine->drv->cpu[cpu].memory_read; mra->start != -1; mra++)
  372.                 if (mra->end >= size && mra->start < lowest) lowest = mra->start;
  373.             for (mwa = Machine->drv->cpu[cpu].memory_write; mwa->start != -1; mwa++)
  374.                 if (mwa->end >= size && mwa->start < lowest) lowest = mwa->start;
  375.  
  376.             /* done if nothing found */
  377.             if (lowest == 0x7fffffff)
  378.                 break;
  379.  
  380.             /* now loop until we find the end of this contiguous block of memory */
  381.             lastend = -1;
  382.             end = lowest;
  383.             while (end != lastend)
  384.             {
  385.                 lastend = end;
  386.  
  387.                 /* find the base of the lowest memory region that extends past the end */
  388.                 for (mra = Machine->drv->cpu[cpu].memory_read; mra->start != -1; mra++)
  389.                     if (mra->start <= end && mra->end > end) end = mra->end + 1;
  390.                 for (mwa = Machine->drv->cpu[cpu].memory_write; mwa->start != -1; mwa++)
  391.                     if (mwa->start <= end && mwa->end > end) end = mwa->end + 1;
  392.             }
  393.  
  394.             /* time to allocate */
  395.             ext->start = lowest;
  396.             ext->end = end - 1;
  397.             ext->region = region;
  398.             ext->data = malloc (end - lowest);
  399.  
  400.             /* if that fails, we're through */
  401.             if (!ext->data)
  402.                 return 0;
  403.  
  404.             /* reset the memory */
  405.             memset (ext->data, 0, end - lowest);
  406.             size = ext->end + 1;
  407.             ext++;
  408.         }
  409.     }
  410.  
  411.     return 1;
  412. }
  413.  
  414.  
  415. unsigned char *findmemorychunk(int cpu, int offset, int *chunkstart, int *chunkend)
  416. {
  417.     int region = REGION_CPU1+cpu;
  418.     struct ExtMemory *ext;
  419.  
  420.     /* look in external memory first */
  421.     for (ext = ext_memory; ext->data; ext++)
  422.         if (ext->region == region && ext->start <= offset && ext->end >= offset)
  423.         {
  424.             *chunkstart = ext->start;
  425.             *chunkend = ext->end;
  426.             return ext->data;
  427.         }
  428.  
  429.     /* return RAM */
  430.     *chunkstart = 0;
  431.     *chunkend = memory_region_length(region) - 1;
  432.     return ramptr[cpu];
  433. }
  434.  
  435.  
  436. unsigned char *memory_find_base (int cpu, int offset)
  437. {
  438.     int region = REGION_CPU1+cpu;
  439.     struct ExtMemory *ext;
  440.  
  441.     /* look in external memory first */
  442.     for (ext = ext_memory; ext->data; ext++)
  443.         if (ext->region == region && ext->start <= offset && ext->end >= offset)
  444.             return ext->data + (offset - ext->start);
  445.  
  446.     return ramptr[cpu] + offset;
  447. }
  448.  
  449. /* make these static so they can be used in a callback by game drivers */
  450.  
  451. static int rdelement_max = 0;
  452. static int wrelement_max = 0;
  453. static int rdhard_max = HT_USER;
  454. static int wrhard_max = HT_USER;
  455.  
  456. /* return = FALSE:can't allocate element memory */
  457. int memory_init(void)
  458. {
  459.     int i, cpu;
  460.     const struct MemoryReadAddress *memoryread;
  461.     const struct MemoryWriteAddress *memorywrite;
  462.     const struct MemoryReadAddress *mra;
  463.     const struct MemoryWriteAddress *mwa;
  464.     const struct IOReadPort *ioread;
  465.     const struct IOWritePort *iowrite;
  466.     MHELE hardware;
  467.     int abits1,abits2,abits3,abitsmin;
  468.     rdelement_max = 0;
  469.     wrelement_max = 0;
  470.     rdhard_max = HT_USER;
  471.     wrhard_max = HT_USER;
  472.  
  473.     for( cpu = 0 ; cpu < MAX_CPU ; cpu++ )
  474.         cur_mr_element[cpu] = cur_mw_element[cpu] = 0;
  475.  
  476.     ophw = 0xff;
  477.  
  478.     /* ASG 980121 -- allocate external memory */
  479.     if (!memory_allocate_ext ())
  480.         return 0;
  481.  
  482.     for( cpu = 0 ; cpu < cpu_gettotalcpu() ; cpu++ )
  483.     {
  484.         const struct MemoryReadAddress *_mra;
  485.         const struct MemoryWriteAddress *_mwa;
  486.  
  487.         setOPbasefunc[cpu] = NULL;
  488.  
  489.         ramptr[cpu] = romptr[cpu] = memory_region(REGION_CPU1+cpu);
  490.  
  491.         /* initialize the memory base pointers for memory hooks */
  492.         _mra = Machine->drv->cpu[cpu].memory_read;
  493.         if (_mra)
  494.         {
  495.             while (_mra->start != -1)
  496.             {
  497. //                if (_mra->base) *_mra->base = memory_find_base (cpu, _mra->start);
  498. //                if (_mra->size) *_mra->size = _mra->end - _mra->start + 1;
  499.                 _mra++;
  500.             }
  501.         }
  502.         _mwa = Machine->drv->cpu[cpu].memory_write;
  503.         if (_mwa)
  504.         {
  505.             while (_mwa->start != -1)
  506.             {
  507.                 if (_mwa->base) *_mwa->base = memory_find_base (cpu, _mwa->start);
  508.                 if (_mwa->size) *_mwa->size = _mwa->end - _mwa->start + 1;
  509.                 _mwa++;
  510.             }
  511.         }
  512.  
  513.         /* initialize port structures */
  514.         readport_size[cpu] = 0;
  515.         writeport_size[cpu] = 0;
  516.         readport[cpu] = 0;
  517.         writeport[cpu] = 0;
  518.  
  519.         /* install port handlers - at least an empty one */
  520.         ioread = Machine->drv->cpu[cpu].port_read;
  521.         if (ioread == 0)  ioread = empty_readport;
  522.  
  523.         while (1)
  524.         {
  525.             if (install_port_read_handler_common(cpu, ioread->start, ioread->end, ioread->handler, 0) == 0)
  526.             {
  527.                 memory_shutdown();
  528.                 return 0;
  529.             }
  530.  
  531.             if (ioread->start == -1)  break;
  532.  
  533.             ioread++;
  534.         }
  535.  
  536.  
  537.         iowrite = Machine->drv->cpu[cpu].port_write;
  538.         if (iowrite == 0)  iowrite = empty_writeport;
  539.  
  540.         while (1)
  541.         {
  542.             if (install_port_write_handler_common(cpu, iowrite->start, iowrite->end, iowrite->handler, 0) == 0)
  543.             {
  544.                 memory_shutdown();
  545.                 return 0;
  546.             }
  547.  
  548.             if (iowrite->start == -1)  break;
  549.  
  550.             iowrite++;
  551.         }
  552.  
  553.         portmask[cpu] = 0xffff;
  554. #if (HAS_Z80)
  555.         if ((Machine->drv->cpu[cpu].cpu_type & ~CPU_FLAGS_MASK) == CPU_Z80 &&
  556.             (Machine->drv->cpu[cpu].cpu_type & CPU_16BIT_PORT) == 0)
  557.             portmask[cpu] = 0xff;
  558. #endif
  559.     }
  560.  
  561.     /* initialize grobal handler */
  562.     for( i = 0 ; i < MH_HARDMAX ; i++ ){
  563.         memoryreadoffset[i] = 0;
  564.         memorywriteoffset[i] = 0;
  565.     }
  566.     /* bank memory */
  567.     for (i = 1; i <= MAX_BANKS; i++)
  568.     {
  569.         memoryreadhandler[i] = bank_read_handler[i];
  570.         memorywritehandler[i] = bank_write_handler[i];
  571.     }
  572.     /* non map memory */
  573.     memoryreadhandler[HT_NON] = mrh_error;
  574.     memorywritehandler[HT_NON] = mwh_error;
  575.     /* NOP memory */
  576.     memoryreadhandler[HT_NOP] = mrh_nop;
  577.     memorywritehandler[HT_NOP] = mwh_nop;
  578.     /* RAMROM memory */
  579.     memorywritehandler[HT_RAMROM] = mwh_ramrom;
  580.     /* ROM memory */
  581.     memorywritehandler[HT_ROM] = mwh_rom;
  582.  
  583.     /* if any CPU is 21-bit or more, we change the error handlers to be more benign */
  584.     for (cpu = 0; cpu < cpu_gettotalcpu(); cpu++)
  585.         if (ADDRESS_BITS (cpu) >= 21)
  586.         {
  587.             memoryreadhandler[HT_NON] = mrh_error_sparse;
  588.             memorywritehandler[HT_NON] = mwh_error_sparse;
  589. #if (HAS_TMS34010)
  590.             if ((Machine->drv->cpu[cpu].cpu_type & ~CPU_FLAGS_MASK)==CPU_TMS34010)
  591.             {
  592.                 memoryreadhandler[HT_NON] = mrh_error_sparse_bit;
  593.                 memorywritehandler[HT_NON] = mwh_error_sparse_bit;
  594.             }
  595. #endif
  596.         }
  597.  
  598.     for( cpu = 0 ; cpu < cpu_gettotalcpu() ; cpu++ )
  599.     {
  600.         /* cpu selection */
  601.         abits1 = ABITS1 (cpu);
  602.         abits2 = ABITS2 (cpu);
  603.         abits3 = ABITS3 (cpu);
  604.         abitsmin = ABITSMIN (cpu);
  605.  
  606.         /* element shifter , mask set */
  607.         mhshift[cpu][0] = (abits2+abits3);
  608.         mhshift[cpu][1] = abits3;            /* 2nd */
  609.         mhshift[cpu][2] = 0;                /* 3rd (used by set_element)*/
  610.         mhmask[cpu][0]    = MHMASK(abits1);        /*1st(used by set_element)*/
  611.         mhmask[cpu][1]    = MHMASK(abits2);        /*2nd*/
  612.         mhmask[cpu][2]    = MHMASK(abits3);        /*3rd*/
  613.  
  614.         /* allocate current element */
  615.         if( (cur_mr_element[cpu] = (MHELE *)malloc(sizeof(MHELE)<<abits1)) == 0 )
  616.         {
  617.             memory_shutdown();
  618.             return 0;
  619.         }
  620.         if( (cur_mw_element[cpu] = (MHELE *)malloc(sizeof(MHELE)<<abits1)) == 0 )
  621.         {
  622.             memory_shutdown();
  623.             return 0;
  624.         }
  625.  
  626.         /* initialize curent element table */
  627.         for( i = 0 ; i < (1<<abits1) ; i++ )
  628.         {
  629.             cur_mr_element[cpu][i] = HT_NON;    /* no map memory */
  630.             cur_mw_element[cpu][i] = HT_NON;    /* no map memory */
  631.         }
  632.  
  633.         memoryread = Machine->drv->cpu[cpu].memory_read;
  634.         memorywrite = Machine->drv->cpu[cpu].memory_write;
  635.  
  636.         /* memory read handler build */
  637.         if (memoryread)
  638.         {
  639.             mra = memoryread;
  640.             while (mra->start != -1) mra++;
  641.             mra--;
  642.  
  643.             while (mra >= memoryread)
  644.             {
  645.                 mem_read_handler handler = mra->handler;
  646.  
  647. /* work around a compiler bug */
  648. #ifdef SGI_FIX_MWA_NOP
  649.                 if ((FPTR)handler == (FPTR)MRA_NOP) {
  650.                     hardware = HT_NOP;
  651.                 } else {
  652. #endif
  653.                 switch ((FPTR)handler)
  654.                 {
  655.                 case (FPTR)MRA_RAM:
  656.                 case (FPTR)MRA_ROM:
  657.                     hardware = HT_RAM;    /* sprcial case ram read */
  658.                     break;
  659.                 case (FPTR)MRA_BANK1:
  660.                 case (FPTR)MRA_BANK2:
  661.                 case (FPTR)MRA_BANK3:
  662.                 case (FPTR)MRA_BANK4:
  663.                 case (FPTR)MRA_BANK5:
  664.                 case (FPTR)MRA_BANK6:
  665.                 case (FPTR)MRA_BANK7:
  666.                 case (FPTR)MRA_BANK8:
  667.                 case (FPTR)MRA_BANK9:
  668.                 case (FPTR)MRA_BANK10:
  669.                 case (FPTR)MRA_BANK11:
  670.                 case (FPTR)MRA_BANK12:
  671.                 case (FPTR)MRA_BANK13:
  672.                 case (FPTR)MRA_BANK14:
  673.                 case (FPTR)MRA_BANK15:
  674.                 case (FPTR)MRA_BANK16:
  675.                 {
  676.                     hardware = (int)MRA_BANK1 - (int)handler + 1;
  677.                     memoryreadoffset[hardware] = bankreadoffset[hardware] = mra->start;
  678.                     cpu_bankbase[hardware] = memory_find_base(cpu, mra->start);
  679.                     break;
  680.                 }
  681.                 case (FPTR)MRA_NOP:
  682.                     hardware = HT_NOP;
  683.                     break;
  684.                 default:
  685.                     /* create newer hardware handler */
  686.                     if( rdhard_max == MH_HARDMAX )
  687.                     {
  688.                         logerror("read memory hardware pattern over !\n");
  689.                         hardware = 0;
  690.                     }
  691.                     else
  692.                     {
  693.                         /* regist hardware function */
  694.                         hardware = rdhard_max++;
  695.                         memoryreadhandler[hardware] = handler;
  696.                         memoryreadoffset[hardware] = mra->start;
  697.                     }
  698.                 }
  699. #ifdef SGI_FIX_MWA_NOP
  700.                 }
  701. #endif
  702.                 /* hardware element table make */
  703.                 set_element( cpu , cur_mr_element[cpu] ,
  704.                     (((unsigned int) mra->start) >> abitsmin) ,
  705.                     (((unsigned int) mra->end) >> abitsmin) ,
  706.                     hardware , readhardware , &rdelement_max );
  707.  
  708.                 mra--;
  709.             }
  710.         }
  711.  
  712.         /* memory write handler build */
  713.         if (memorywrite)
  714.         {
  715.             mwa = memorywrite;
  716.             while (mwa->start != -1) mwa++;
  717.             mwa--;
  718.  
  719.             while (mwa >= memorywrite)
  720.             {
  721.                 mem_write_handler handler = mwa->handler;
  722. #ifdef SGI_FIX_MWA_NOP
  723.                 if ((FPTR)handler == (FPTR)MWA_NOP) {
  724.                     hardware = HT_NOP;
  725.                 } else {
  726. #endif
  727.                 switch( (FPTR)handler )
  728.                 {
  729.                 case (FPTR)MWA_RAM:
  730.                     hardware = HT_RAM;    /* sprcial case ram write */
  731.                     break;
  732.                 case (FPTR)MWA_BANK1:
  733.                 case (FPTR)MWA_BANK2:
  734.                 case (FPTR)MWA_BANK3:
  735.                 case (FPTR)MWA_BANK4:
  736.                 case (FPTR)MWA_BANK5:
  737.                 case (FPTR)MWA_BANK6:
  738.                 case (FPTR)MWA_BANK7:
  739.                 case (FPTR)MWA_BANK8:
  740.                 case (FPTR)MWA_BANK9:
  741.                 case (FPTR)MWA_BANK10:
  742.                 case (FPTR)MWA_BANK11:
  743.                 case (FPTR)MWA_BANK12:
  744.                 case (FPTR)MWA_BANK13:
  745.                 case (FPTR)MWA_BANK14:
  746.                 case (FPTR)MWA_BANK15:
  747.                 case (FPTR)MWA_BANK16:
  748.                 {
  749.                     hardware = (int)MWA_BANK1 - (int)handler + 1;
  750.                     memorywriteoffset[hardware] = bankwriteoffset[hardware] = mwa->start;
  751.                     cpu_bankbase[hardware] = memory_find_base(cpu, mwa->start);
  752.                     break;
  753.                 }
  754.                 case (FPTR)MWA_NOP:
  755.                     hardware = HT_NOP;
  756.                     break;
  757.                 case (FPTR)MWA_RAMROM:
  758.                     hardware = HT_RAMROM;
  759.                     break;
  760.                 case (FPTR)MWA_ROM:
  761.                     hardware = HT_ROM;
  762.                     break;
  763.                 default:
  764.                     /* create newer hardware handler */
  765.                     if( wrhard_max == MH_HARDMAX ){
  766.                         logerror("write memory hardware pattern over !\n");
  767.                         hardware = 0;
  768.                     }else{
  769.                         /* regist hardware function */
  770.                         hardware = wrhard_max++;
  771.                         memorywritehandler[hardware] = handler;
  772.                         memorywriteoffset[hardware]  = mwa->start;
  773.                     }
  774.                 }
  775. #ifdef SGI_FIX_MWA_NOP
  776.                 }
  777. #endif
  778.                 /* hardware element table make */
  779.                 set_element( cpu , cur_mw_element[cpu] ,
  780.                     (int) (((unsigned int) mwa->start) >> abitsmin) ,
  781.                     (int) (((unsigned int) mwa->end) >> abitsmin) ,
  782.                     hardware , (MHELE *)writehardware , &wrelement_max );
  783.  
  784.                 mwa--;
  785.             }
  786.         }
  787.     }
  788.  
  789.     logerror("used read  elements %d/%d , functions %d/%d\n"
  790.             ,rdelement_max,MH_ELEMAX , rdhard_max,MH_HARDMAX );
  791.     logerror("used write elements %d/%d , functions %d/%d\n"
  792.             ,wrelement_max,MH_ELEMAX , wrhard_max,MH_HARDMAX );
  793.  
  794. #ifdef MEM_DUMP
  795.     mem_dump();
  796. #endif
  797.     return 1;    /* ok */
  798. }
  799.  
  800. void memory_set_opcode_base(int cpu,unsigned char *base)
  801. {
  802.     romptr[cpu] = base;
  803. }
  804.  
  805.  
  806. void memorycontextswap(int activecpu)
  807. {
  808.     cpu_bankbase[0] = ramptr[activecpu];
  809.  
  810.     cur_mrhard = cur_mr_element[activecpu];
  811.     cur_mwhard = cur_mw_element[activecpu];
  812.  
  813.     /* ASG: port speedup */
  814.     cur_readport = readport[activecpu];
  815.     cur_writeport = writeport[activecpu];
  816.     cur_portmask = portmask[activecpu];
  817.  
  818.     OPbasefunc = setOPbasefunc[activecpu];
  819.  
  820.     /* op code memory pointer */
  821.     ophw = HT_RAM;
  822.     OP_RAM = cpu_bankbase[0];
  823.     OP_ROM = romptr[activecpu];
  824. }
  825.  
  826. void memory_shutdown(void)
  827. {
  828.     struct ExtMemory *ext;
  829.     int cpu;
  830.  
  831.     for( cpu = 0 ; cpu < MAX_CPU ; cpu++ )
  832.     {
  833.         if( cur_mr_element[cpu] != 0 )
  834.         {
  835.             free( cur_mr_element[cpu] );
  836.             cur_mr_element[cpu] = 0;
  837.         }
  838.         if( cur_mw_element[cpu] != 0 )
  839.         {
  840.             free( cur_mw_element[cpu] );
  841.             cur_mw_element[cpu] = 0;
  842.         }
  843.  
  844.         if (readport[cpu] != 0)
  845.         {
  846.             free(readport[cpu]);
  847.             readport[cpu] = 0;
  848.         }
  849.  
  850.         if (writeport[cpu] != 0)
  851.         {
  852.             free(writeport[cpu]);
  853.             writeport[cpu] = 0;
  854.         }
  855.     }
  856.  
  857.     /* ASG 980121 -- free all the external memory */
  858.     for (ext = ext_memory; ext->data; ext++)
  859.         free (ext->data);
  860.     memset (ext_memory, 0, sizeof (ext_memory));
  861. }
  862.  
  863.  
  864.  
  865. /***************************************************************************
  866.  
  867.   Perform a memory read. This function is called by the CPU emulation.
  868.  
  869. ***************************************************************************/
  870.  
  871. /* use these constants to define which type of memory handler to build */
  872. #define TYPE_8BIT                    0        /* 8-bit aligned */
  873. #define TYPE_16BIT_BE                1        /* 16-bit aligned, big-endian */
  874. #define TYPE_16BIT_LE                2        /* 16-bit aligned, little-endian */
  875.  
  876. #define CAN_BE_MISALIGNED            0        /* word/dwords can be read on non-16-bit boundaries */
  877. #define ALWAYS_ALIGNED                1        /* word/dwords are always read on 16-bit boundaries */
  878.  
  879. /* stupid workarounds so that we can generate an address mask that works even for 32 bits */
  880. #define ADDRESS_TOPBIT(abits)        (1UL << (ABITS1_##abits + ABITS2_##abits + ABITS_MIN_##abits - 1))
  881. #define ADDRESS_MASK(abits)         (ADDRESS_TOPBIT(abits) | (ADDRESS_TOPBIT(abits) - 1))
  882.  
  883.  
  884. /* generic byte-sized read handler */
  885. #define READBYTE(name,type,abits)                                                        \
  886. data_t name(offs_t address)                                                             \
  887. {                                                                                        \
  888.     MHELE hw;                                                                            \
  889.                                                                                         \
  890.     /* first-level lookup */                                                            \
  891.     hw = cur_mrhard[(UINT32)address >> (ABITS2_##abits + ABITS_MIN_##abits)];            \
  892.                                                                                         \
  893.     /* for compatibility with setbankhandler, 8-bit systems must call handlers */        \
  894.     /* for banked memory reads/writes */                                                \
  895.     if (type == TYPE_8BIT && hw == HT_RAM)                                                \
  896.         return cpu_bankbase[HT_RAM][address];                                            \
  897.     else if (type != TYPE_8BIT && hw <= HT_BANKMAX)                                     \
  898.     {                                                                                    \
  899.         if (type == TYPE_16BIT_BE)                                                        \
  900.             return cpu_bankbase[hw][BYTE_XOR_BE(address) - memoryreadoffset[hw]];        \
  901.         else if (type == TYPE_16BIT_LE)                                                 \
  902.             return cpu_bankbase[hw][BYTE_XOR_LE(address) - memoryreadoffset[hw]];        \
  903.     }                                                                                    \
  904.                                                                                         \
  905.     /* second-level lookup */                                                            \
  906.     if (hw >= MH_HARDMAX)                                                                \
  907.     {                                                                                    \
  908.         hw -= MH_HARDMAX;                                                                \
  909.         hw = readhardware[(hw << MH_SBITS) + (((UINT32)address >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))];    \
  910.                                                                                         \
  911.         /* for compatibility with setbankhandler, 8-bit systems must call handlers */    \
  912.         /* for banked memory reads/writes */                                            \
  913.         if (type == TYPE_8BIT && hw == HT_RAM)                                            \
  914.             return cpu_bankbase[HT_RAM][address];                                        \
  915.         else if (type != TYPE_8BIT && hw <= HT_BANKMAX)                                 \
  916.         {                                                                                \
  917.             if (type == TYPE_16BIT_BE)                                                    \
  918.                 return cpu_bankbase[hw][BYTE_XOR_BE(address) - memoryreadoffset[hw]];    \
  919.             else if (type == TYPE_16BIT_LE)                                             \
  920.                 return cpu_bankbase[hw][BYTE_XOR_LE(address) - memoryreadoffset[hw]];    \
  921.         }                                                                                \
  922.     }                                                                                    \
  923.                                                                                         \
  924.     /* fall back to handler */                                                            \
  925.     if (type == TYPE_8BIT)                                                                \
  926.         return (*memoryreadhandler[hw])(address - memoryreadoffset[hw]);                \
  927.     else                                                                                \
  928.     {                                                                                    \
  929.         int shift = (address & 1) << 3;                                                 \
  930.         int data = (*memoryreadhandler[hw])((address & ~1) - memoryreadoffset[hw]);     \
  931.         if (type == TYPE_16BIT_BE)                                                        \
  932.             return (data >> (shift ^ 8)) & 0xff;                                        \
  933.         else if (type == TYPE_16BIT_LE)                                                 \
  934.             return (data >> shift) & 0xff;                                                \
  935.     }                                                                                    \
  936. }
  937.  
  938. /* generic word-sized read handler (16-bit aligned only!) */
  939. #define READWORD(name,type,abits,align)                                                 \
  940. data_t name##_word(offs_t address)                                                        \
  941. {                                                                                        \
  942.     MHELE hw;                                                                            \
  943.                                                                                         \
  944.     /* only supports 16-bit memory systems */                                            \
  945.     if (type == TYPE_8BIT)                                                                \
  946.         printf("Unsupported type for READWORD macro!\n");                               \
  947.                                                                                         \
  948.     /* handle aligned case first */                                                     \
  949.     if (align == ALWAYS_ALIGNED || !(address & 1))                                        \
  950.     {                                                                                    \
  951.         /* first-level lookup */                                                        \
  952.         hw = cur_mrhard[(UINT32)address >> (ABITS2_##abits + ABITS_MIN_##abits)];        \
  953.         if (hw <= HT_BANKMAX)                                                            \
  954.             return READ_WORD(&cpu_bankbase[hw][address - memoryreadoffset[hw]]);        \
  955.                                                                                         \
  956.         /* second-level lookup */                                                        \
  957.         if (hw >= MH_HARDMAX)                                                            \
  958.         {                                                                                \
  959.             hw -= MH_HARDMAX;                                                            \
  960.             hw = readhardware[(hw << MH_SBITS) + (((UINT32)address >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))];    \
  961.             if (hw <= HT_BANKMAX)                                                        \
  962.                 return READ_WORD(&cpu_bankbase[hw][address - memoryreadoffset[hw]]);    \
  963.         }                                                                                \
  964.                                                                                         \
  965.         /* fall back to handler */                                                        \
  966.         return (*memoryreadhandler[hw])(address - memoryreadoffset[hw]);                \
  967.     }                                                                                    \
  968.                                                                                         \
  969.     /* unaligned case */                                                                \
  970.     else if (type == TYPE_16BIT_BE)                                                     \
  971.     {                                                                                    \
  972.         int data = name(address) << 8;                                                    \
  973.         return data | (name(address + 1) & 0xff);                                        \
  974.     }                                                                                    \
  975.     else if (type == TYPE_16BIT_LE)                                                     \
  976.     {                                                                                    \
  977.         int data = name(address) & 0xff;                                                \
  978.         return data | (name(address + 1) << 8);                                         \
  979.     }                                                                                    \
  980. }
  981.  
  982. /* generic dword-sized read handler (16-bit aligned only!) */
  983. #define READLONG(name,type,abits,align)                                                 \
  984. data_t name##_dword(offs_t address)                                                     \
  985. {                                                                                        \
  986.     UINT16 word1, word2;                                                                \
  987.     MHELE hw1, hw2;                                                                     \
  988.                                                                                         \
  989.     /* only supports 16-bit memory systems */                                            \
  990.     if (type == TYPE_8BIT)                                                                \
  991.         printf("Unsupported type for READWORD macro!\n");                               \
  992.                                                                                         \
  993.     /* handle aligned case first */                                                     \
  994.     if (align == ALWAYS_ALIGNED || !(address & 1))                                        \
  995.     {                                                                                    \
  996.         int address2 = (address + 2) & ADDRESS_MASK(abits);                             \
  997.                                                                                         \
  998.         /* first-level lookup */                                                        \
  999.         hw1 = cur_mrhard[(UINT32)address >> (ABITS2_##abits + ABITS_MIN_##abits)];        \
  1000.         hw2 = cur_mrhard[(UINT32)address2 >> (ABITS2_##abits + ABITS_MIN_##abits)];     \
  1001.                                                                                         \
  1002.         /* second-level lookup */                                                        \
  1003.         if (hw1 >= MH_HARDMAX)                                                            \
  1004.         {                                                                                \
  1005.             hw1 -= MH_HARDMAX;                                                            \
  1006.             hw1 = readhardware[(hw1 << MH_SBITS) + (((UINT32)address >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))];    \
  1007.         }                                                                                \
  1008.         if (hw2 >= MH_HARDMAX)                                                            \
  1009.         {                                                                                \
  1010.             hw2 -= MH_HARDMAX;                                                            \
  1011.             hw2 = readhardware[(hw2 << MH_SBITS) + (((UINT32)address2 >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))]; \
  1012.         }                                                                                \
  1013.                                                                                         \
  1014.         /* process each word */                                                         \
  1015.         if (hw1 <= HT_BANKMAX)                                                            \
  1016.             word1 = READ_WORD(&cpu_bankbase[hw1][address - memoryreadoffset[hw1]]);     \
  1017.         else                                                                            \
  1018.             word1 = (*memoryreadhandler[hw1])(address - memoryreadoffset[hw1]);         \
  1019.         if (hw2 <= HT_BANKMAX)                                                            \
  1020.             word2 = READ_WORD(&cpu_bankbase[hw2][address2 - memoryreadoffset[hw2]]);    \
  1021.         else                                                                            \
  1022.             word2 = (*memoryreadhandler[hw2])(address2 - memoryreadoffset[hw2]);        \
  1023.                                                                                         \
  1024.         /* fall back to handler */                                                        \
  1025.         if (type == TYPE_16BIT_BE)                                                        \
  1026.             return (word1 << 16) | (word2 & 0xffff);                                    \
  1027.         else if (type == TYPE_16BIT_LE)                                                 \
  1028.             return (word1 & 0xffff) | (word2 << 16);                                    \
  1029.     }                                                                                    \
  1030.                                                                                         \
  1031.     /* unaligned case */                                                                \
  1032.     else if (type == TYPE_16BIT_BE)                                                     \
  1033.     {                                                                                    \
  1034.         int data = name(address) << 24;                                                 \
  1035.         data |= name##_word(address + 1) << 8;                                            \
  1036.         return data | (name(address + 3) & 0xff);                                        \
  1037.     }                                                                                    \
  1038.     else if (type == TYPE_16BIT_LE)                                                     \
  1039.     {                                                                                    \
  1040.         int data = name(address) & 0xff;                                                \
  1041.         data |= name##_word(address + 1) << 8;                                            \
  1042.         return data | (name(address + 3) << 24);                                        \
  1043.     }                                                                                    \
  1044. }
  1045.  
  1046.  
  1047. /* the handlers we need to generate */
  1048. READBYTE(cpu_readmem16,    TYPE_8BIT,      16)
  1049. READBYTE(cpu_readmem20,    TYPE_8BIT,      20)
  1050. READBYTE(cpu_readmem21,    TYPE_8BIT,      21)
  1051.  
  1052. READBYTE(cpu_readmem16bew, TYPE_16BIT_BE, 16BEW)
  1053. READWORD(cpu_readmem16bew, TYPE_16BIT_BE, 16BEW, ALWAYS_ALIGNED)
  1054.  
  1055. READBYTE(cpu_readmem16lew, TYPE_16BIT_LE, 16LEW)
  1056. READWORD(cpu_readmem16lew, TYPE_16BIT_LE, 16LEW, ALWAYS_ALIGNED)
  1057.  
  1058. READBYTE(cpu_readmem24,    TYPE_8BIT,      24)
  1059.  
  1060. READBYTE(cpu_readmem24bew, TYPE_16BIT_BE, 24BEW)
  1061. READWORD(cpu_readmem24bew, TYPE_16BIT_BE, 24BEW, CAN_BE_MISALIGNED)
  1062. READLONG(cpu_readmem24bew, TYPE_16BIT_BE, 24BEW, CAN_BE_MISALIGNED)
  1063.  
  1064. READBYTE(cpu_readmem29,    TYPE_16BIT_LE, 29)
  1065. READWORD(cpu_readmem29,    TYPE_16BIT_LE, 29,     CAN_BE_MISALIGNED)
  1066. READLONG(cpu_readmem29,    TYPE_16BIT_LE, 29,     CAN_BE_MISALIGNED)
  1067.  
  1068. READBYTE(cpu_readmem32,    TYPE_16BIT_BE, 32)
  1069. READWORD(cpu_readmem32,    TYPE_16BIT_BE, 32,     CAN_BE_MISALIGNED)
  1070. READLONG(cpu_readmem32,    TYPE_16BIT_BE, 32,     CAN_BE_MISALIGNED)
  1071.  
  1072. READBYTE(cpu_readmem32lew, TYPE_16BIT_LE, 32LEW)
  1073. READWORD(cpu_readmem32lew, TYPE_16BIT_LE, 32LEW, CAN_BE_MISALIGNED)
  1074. READLONG(cpu_readmem32lew, TYPE_16BIT_LE, 32LEW, CAN_BE_MISALIGNED)
  1075.  
  1076.  
  1077. /***************************************************************************
  1078.  
  1079.   Perform a memory write. This function is called by the CPU emulation.
  1080.  
  1081. ***************************************************************************/
  1082.  
  1083. /* generic byte-sized write handler */
  1084. #define WRITEBYTE(name,type,abits)                                                        \
  1085. void name(offs_t address,data_t data)                                                    \
  1086. {                                                                                        \
  1087.     MHELE hw;                                                                            \
  1088.                                                                                         \
  1089.     /* first-level lookup */                                                            \
  1090.     hw = cur_mwhard[(UINT32)address >> (ABITS2_##abits + ABITS_MIN_##abits)];            \
  1091.                                                                                         \
  1092.     /* for compatibility with setbankhandler, 8-bit systems must call handlers */        \
  1093.     /* for banked memory reads/writes */                                                \
  1094.     if (type == TYPE_8BIT && hw == HT_RAM)                                                \
  1095.     {                                                                                    \
  1096.         cpu_bankbase[HT_RAM][address] = data;                                            \
  1097.         return;                                                                         \
  1098.     }                                                                                    \
  1099.     else if (type != TYPE_8BIT && hw <= HT_BANKMAX)                                     \
  1100.     {                                                                                    \
  1101.         if (type == TYPE_16BIT_BE)                                                        \
  1102.             cpu_bankbase[hw][BYTE_XOR_BE(address) - memorywriteoffset[hw]] = data;        \
  1103.         else if (type == TYPE_16BIT_LE)                                                 \
  1104.             cpu_bankbase[hw][BYTE_XOR_LE(address) - memorywriteoffset[hw]] = data;        \
  1105.         return;                                                                         \
  1106.     }                                                                                    \
  1107.                                                                                         \
  1108.     /* second-level lookup */                                                            \
  1109.     if (hw >= MH_HARDMAX)                                                                \
  1110.     {                                                                                    \
  1111.         hw -= MH_HARDMAX;                                                                \
  1112.         hw = writehardware[(hw << MH_SBITS) + (((UINT32)address >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))];    \
  1113.                                                                                         \
  1114.         /* for compatibility with setbankhandler, 8-bit systems must call handlers */    \
  1115.         /* for banked memory reads/writes */                                            \
  1116.         if (type == TYPE_8BIT && hw == HT_RAM)                                            \
  1117.         {                                                                                \
  1118.             cpu_bankbase[HT_RAM][address] = data;                                        \
  1119.             return;                                                                     \
  1120.         }                                                                                \
  1121.         else if (type != TYPE_8BIT && hw <= HT_BANKMAX)                                 \
  1122.         {                                                                                \
  1123.             if (type == TYPE_16BIT_BE)                                                    \
  1124.                 cpu_bankbase[hw][BYTE_XOR_BE(address) - memorywriteoffset[hw]] = data;    \
  1125.             else if (type == TYPE_16BIT_LE)                                             \
  1126.                 cpu_bankbase[hw][BYTE_XOR_LE(address) - memorywriteoffset[hw]] = data;    \
  1127.             return;                                                                     \
  1128.         }                                                                                \
  1129.     }                                                                                    \
  1130.                                                                                         \
  1131.     /* fall back to handler */                                                            \
  1132.     if (type != TYPE_8BIT)                                                                \
  1133.     {                                                                                    \
  1134.         int shift = (address & 1) << 3;                                                 \
  1135.         if (type == TYPE_16BIT_BE)                                                        \
  1136.             shift ^= 8;                                                                 \
  1137.         data = (0xff000000 >> shift) | ((data & 0xff) << shift);                        \
  1138.         address &= ~1;                                                                    \
  1139.     }                                                                                    \
  1140.     (*memorywritehandler[hw])(address - memorywriteoffset[hw], data);                    \
  1141. }
  1142.  
  1143. /* generic word-sized write handler (16-bit aligned only!) */
  1144. #define WRITEWORD(name,type,abits,align)                                                \
  1145. void name##_word(offs_t address,data_t data)                                            \
  1146. {                                                                                        \
  1147.     MHELE hw;                                                                            \
  1148.                                                                                         \
  1149.     /* only supports 16-bit memory systems */                                            \
  1150.     if (type == TYPE_8BIT)                                                                \
  1151.         printf("Unsupported type for WRITEWORD macro!\n");                              \
  1152.                                                                                         \
  1153.     /* handle aligned case first */                                                     \
  1154.     if (align == ALWAYS_ALIGNED || !(address & 1))                                        \
  1155.     {                                                                                    \
  1156.         /* first-level lookup */                                                        \
  1157.         hw = cur_mwhard[(UINT32)address >> (ABITS2_##abits + ABITS_MIN_##abits)];        \
  1158.         if (hw <= HT_BANKMAX)                                                            \
  1159.         {                                                                                \
  1160.             WRITE_WORD(&cpu_bankbase[hw][address - memorywriteoffset[hw]], data);        \
  1161.             return;                                                                     \
  1162.         }                                                                                \
  1163.                                                                                         \
  1164.         /* second-level lookup */                                                        \
  1165.         if (hw >= MH_HARDMAX)                                                            \
  1166.         {                                                                                \
  1167.             hw -= MH_HARDMAX;                                                            \
  1168.             hw = writehardware[(hw << MH_SBITS) + (((UINT32)address >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))]; \
  1169.             if (hw <= HT_BANKMAX)                                                        \
  1170.             {                                                                            \
  1171.                 WRITE_WORD(&cpu_bankbase[hw][address - memorywriteoffset[hw]], data);    \
  1172.                 return;                                                                 \
  1173.             }                                                                            \
  1174.         }                                                                                \
  1175.                                                                                         \
  1176.         /* fall back to handler */                                                        \
  1177.         (*memorywritehandler[hw])(address - memorywriteoffset[hw], data & 0xffff);        \
  1178.     }                                                                                    \
  1179.                                                                                         \
  1180.     /* unaligned case */                                                                \
  1181.     else if (type == TYPE_16BIT_BE)                                                     \
  1182.     {                                                                                    \
  1183.         name(address, data >> 8);                                                        \
  1184.         name(address + 1, data & 0xff);                                                 \
  1185.     }                                                                                    \
  1186.     else if (type == TYPE_16BIT_LE)                                                     \
  1187.     {                                                                                    \
  1188.         name(address, data & 0xff);                                                     \
  1189.         name(address + 1, data >> 8);                                                    \
  1190.     }                                                                                    \
  1191. }
  1192.  
  1193. /* generic dword-sized write handler (16-bit aligned only!) */
  1194. #define WRITELONG(name,type,abits,align)                                                \
  1195. void name##_dword(offs_t address,data_t data)                                            \
  1196. {                                                                                        \
  1197.     UINT16 word1, word2;                                                                \
  1198.     MHELE hw1, hw2;                                                                     \
  1199.                                                                                         \
  1200.     /* only supports 16-bit memory systems */                                            \
  1201.     if (type == TYPE_8BIT)                                                                \
  1202.         printf("Unsupported type for WRITEWORD macro!\n");                              \
  1203.                                                                                         \
  1204.     /* handle aligned case first */                                                     \
  1205.     if (align == ALWAYS_ALIGNED || !(address & 1))                                        \
  1206.     {                                                                                    \
  1207.         int address2 = (address + 2) & ADDRESS_MASK(abits);                             \
  1208.                                                                                         \
  1209.         /* first-level lookup */                                                        \
  1210.         hw1 = cur_mwhard[(UINT32)address >> (ABITS2_##abits + ABITS_MIN_##abits)];        \
  1211.         hw2 = cur_mwhard[(UINT32)address2 >> (ABITS2_##abits + ABITS_MIN_##abits)];     \
  1212.                                                                                         \
  1213.         /* second-level lookup */                                                        \
  1214.         if (hw1 >= MH_HARDMAX)                                                            \
  1215.         {                                                                                \
  1216.             hw1 -= MH_HARDMAX;                                                            \
  1217.             hw1 = writehardware[(hw1 << MH_SBITS) + (((UINT32)address >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))]; \
  1218.         }                                                                                \
  1219.         if (hw2 >= MH_HARDMAX)                                                            \
  1220.         {                                                                                \
  1221.             hw2 -= MH_HARDMAX;                                                            \
  1222.             hw2 = writehardware[(hw2 << MH_SBITS) + (((UINT32)address2 >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))];    \
  1223.         }                                                                                \
  1224.                                                                                         \
  1225.         /* extract words */                                                             \
  1226.         if (type == TYPE_16BIT_BE)                                                        \
  1227.         {                                                                                \
  1228.             word1 = data >> 16;                                                         \
  1229.             word2 = data & 0xffff;                                                        \
  1230.         }                                                                                \
  1231.         else if (type == TYPE_16BIT_LE)                                                 \
  1232.         {                                                                                \
  1233.             word1 = data & 0xffff;                                                        \
  1234.             word2 = data >> 16;                                                         \
  1235.         }                                                                                \
  1236.                                                                                         \
  1237.         /* process each word */                                                         \
  1238.         if (hw1 <= HT_BANKMAX)                                                            \
  1239.             WRITE_WORD(&cpu_bankbase[hw1][address - memorywriteoffset[hw1]], word1);    \
  1240.         else                                                                            \
  1241.             (*memorywritehandler[hw1])(address - memorywriteoffset[hw1], word1);        \
  1242.         if (hw2 <= HT_BANKMAX)                                                            \
  1243.             WRITE_WORD(&cpu_bankbase[hw2][address2 - memorywriteoffset[hw2]], word2);    \
  1244.         else                                                                            \
  1245.             (*memorywritehandler[hw2])(address2 - memorywriteoffset[hw2], word2);        \
  1246.     }                                                                                    \
  1247.                                                                                         \
  1248.     /* unaligned case */                                                                \
  1249.     else if (type == TYPE_16BIT_BE)                                                     \
  1250.     {                                                                                    \
  1251.         name(address, data >> 24);                                                        \
  1252.         name##_word(address + 1, (data >> 8) & 0xffff);                                 \
  1253.         name(address + 3, data & 0xff);                                                 \
  1254.     }                                                                                    \
  1255.     else if (type == TYPE_16BIT_LE)                                                     \
  1256.     {                                                                                    \
  1257.         name(address, data & 0xff);                                                     \
  1258.         name##_word(address + 1, (data >> 8) & 0xffff);                                 \
  1259.         name(address + 3, data >> 24);                                                    \
  1260.     }                                                                                    \
  1261. }
  1262.  
  1263.  
  1264. /* the handlers we need to generate */
  1265. WRITEBYTE(cpu_writemem16,     TYPE_8BIT,     16)
  1266. WRITEBYTE(cpu_writemem20,     TYPE_8BIT,     20)
  1267. WRITEBYTE(cpu_writemem21,     TYPE_8BIT,     21)
  1268.  
  1269. WRITEBYTE(cpu_writemem16bew, TYPE_16BIT_BE, 16BEW)
  1270. WRITEWORD(cpu_writemem16bew, TYPE_16BIT_BE, 16BEW, ALWAYS_ALIGNED)
  1271.  
  1272. WRITEBYTE(cpu_writemem16lew, TYPE_16BIT_LE, 16LEW)
  1273. WRITEWORD(cpu_writemem16lew, TYPE_16BIT_LE, 16LEW, ALWAYS_ALIGNED)
  1274.  
  1275. WRITEBYTE(cpu_writemem24,     TYPE_8BIT,     24)
  1276.  
  1277. WRITEBYTE(cpu_writemem24bew, TYPE_16BIT_BE, 24BEW)
  1278. WRITEWORD(cpu_writemem24bew, TYPE_16BIT_BE, 24BEW, CAN_BE_MISALIGNED)
  1279. WRITELONG(cpu_writemem24bew, TYPE_16BIT_BE, 24BEW, CAN_BE_MISALIGNED)
  1280.  
  1281. WRITEBYTE(cpu_writemem29,     TYPE_16BIT_LE, 29)
  1282. WRITEWORD(cpu_writemem29,     TYPE_16BIT_LE, 29,    CAN_BE_MISALIGNED)
  1283. WRITELONG(cpu_writemem29,     TYPE_16BIT_LE, 29,    CAN_BE_MISALIGNED)
  1284.  
  1285. WRITEBYTE(cpu_writemem32,     TYPE_16BIT_BE, 32)
  1286. WRITEWORD(cpu_writemem32,     TYPE_16BIT_BE, 32,    CAN_BE_MISALIGNED)
  1287. WRITELONG(cpu_writemem32,     TYPE_16BIT_BE, 32,    CAN_BE_MISALIGNED)
  1288.  
  1289. WRITEBYTE(cpu_writemem32lew, TYPE_16BIT_LE, 32LEW)
  1290. WRITEWORD(cpu_writemem32lew, TYPE_16BIT_LE, 32LEW, CAN_BE_MISALIGNED)
  1291. WRITELONG(cpu_writemem32lew, TYPE_16BIT_LE, 32LEW, CAN_BE_MISALIGNED)
  1292.  
  1293.  
  1294. /***************************************************************************
  1295.  
  1296.   Opcode base changers. This function is called by the CPU emulation.
  1297.  
  1298. ***************************************************************************/
  1299.  
  1300. /* generic opcode base changer */
  1301. #define SETOPBASE(name,abits,shift)                                                     \
  1302. void name(int pc)                                                                        \
  1303. {                                                                                        \
  1304.     MHELE hw;                                                                            \
  1305.                                                                                         \
  1306.     pc = (UINT32)pc >> shift;                                                            \
  1307.                                                                                         \
  1308.     /* allow overrides */                                                                \
  1309.     if (OPbasefunc)                                                                     \
  1310.     {                                                                                    \
  1311.         pc = OPbasefunc(pc);                                                            \
  1312.         if (pc == -1)                                                                    \
  1313.             return;                                                                     \
  1314.     }                                                                                    \
  1315.                                                                                         \
  1316.     /* perform the lookup */                                                            \
  1317.     hw = cur_mrhard[(UINT32)pc >> (ABITS2_##abits + ABITS_MIN_##abits)];                \
  1318.     if (hw >= MH_HARDMAX)                                                                \
  1319.     {                                                                                    \
  1320.         hw -= MH_HARDMAX;                                                                \
  1321.         hw = readhardware[(hw << MH_SBITS) + (((UINT32)pc >> ABITS_MIN_##abits) & MHMASK(ABITS2_##abits))]; \
  1322.     }                                                                                    \
  1323.     ophw = hw;                                                                            \
  1324.                                                                                         \
  1325.     /* RAM or banked memory */                                                            \
  1326.     if (hw <= HT_BANKMAX)                                                                \
  1327.     {                                                                                    \
  1328.         SET_OP_RAMROM(cpu_bankbase[hw] - memoryreadoffset[hw])                            \
  1329.         return;                                                                         \
  1330.     }                                                                                    \
  1331.                                                                                         \
  1332.     /* do not support on callback memory region */                                        \
  1333.     logerror("CPU #%d PC %04x: warning - op-code execute on mapped i/o\n",              \
  1334.                 cpu_getactivecpu(),cpu_get_pc());                                        \
  1335. }
  1336.  
  1337.  
  1338. /* the handlers we need to generate */
  1339. SETOPBASE(cpu_setOPbase16,      16,     0)
  1340. SETOPBASE(cpu_setOPbase16bew, 16BEW, 0)
  1341. SETOPBASE(cpu_setOPbase16lew, 16LEW, 0)
  1342. SETOPBASE(cpu_setOPbase20,      20,     0)
  1343. SETOPBASE(cpu_setOPbase21,      21,     0)
  1344. SETOPBASE(cpu_setOPbase24,      24,     0)
  1345. SETOPBASE(cpu_setOPbase24bew, 24BEW, 0)
  1346. SETOPBASE(cpu_setOPbase29,      29,     3)
  1347. SETOPBASE(cpu_setOPbase32,      32,     0)
  1348. SETOPBASE(cpu_setOPbase32lew, 32LEW, 0)
  1349.  
  1350.  
  1351. /***************************************************************************
  1352.  
  1353.   Perform an I/O port read. This function is called by the CPU emulation.
  1354.  
  1355. ***************************************************************************/
  1356. int cpu_readport(int port)
  1357. {
  1358.     const struct IOReadPort *iorp = cur_readport;
  1359.  
  1360.     port &= cur_portmask;
  1361.  
  1362.     /* search the handlers. The order is as follows: first the dynamically installed
  1363.        handlers are searched, followed by the static ones in whatever order they were
  1364.        specified in the driver */
  1365.     while (iorp->start != -1)
  1366.     {
  1367.         if (port >= iorp->start && port <= iorp->end)
  1368.         {
  1369.             mem_read_handler handler = iorp->handler;
  1370.  
  1371.  
  1372.             if (handler == IORP_NOP) return 0;
  1373.             else return (*handler)(port - iorp->start);
  1374.         }
  1375.  
  1376.         iorp++;
  1377.     }
  1378.  
  1379.     logerror("CPU #%d PC %04x: warning - read unmapped I/O port %02x\n",cpu_getactivecpu(),cpu_get_pc(),port);
  1380.     return 0;
  1381. }
  1382.  
  1383.  
  1384. /***************************************************************************
  1385.  
  1386.   Perform an I/O port write. This function is called by the CPU emulation.
  1387.  
  1388. ***************************************************************************/
  1389. void cpu_writeport(int port, int value)
  1390. {
  1391.     const struct IOWritePort *iowp = cur_writeport;
  1392.  
  1393.     port &= cur_portmask;
  1394.  
  1395.     /* search the handlers. The order is as follows: first the dynamically installed
  1396.        handlers are searched, followed by the static ones in whatever order they were
  1397.        specified in the driver */
  1398.     while (iowp->start != -1)
  1399.     {
  1400.         if (port >= iowp->start && port <= iowp->end)
  1401.         {
  1402.             mem_write_handler handler = iowp->handler;
  1403.  
  1404.  
  1405.             if (handler == IOWP_NOP) return;
  1406.             else (*handler)(port - iowp->start,value);
  1407.  
  1408.             return;
  1409.         }
  1410.  
  1411.         iowp++;
  1412.     }
  1413.  
  1414.     logerror("CPU #%d PC %04x: warning - write %02x to unmapped I/O port %02x\n",cpu_getactivecpu(),cpu_get_pc(),value,port);
  1415. }
  1416.  
  1417.  
  1418. /* set readmemory handler for bank memory  */
  1419. void cpu_setbankhandler_r(int bank, mem_read_handler handler)
  1420. {
  1421.     int offset = 0;
  1422.     MHELE hardware;
  1423.  
  1424.     switch( (FPTR)handler )
  1425.     {
  1426.     case (FPTR)MRA_RAM:
  1427.     case (FPTR)MRA_ROM:
  1428.         handler = mrh_ram;
  1429.         break;
  1430.     case (FPTR)MRA_BANK1:
  1431.     case (FPTR)MRA_BANK2:
  1432.     case (FPTR)MRA_BANK3:
  1433.     case (FPTR)MRA_BANK4:
  1434.     case (FPTR)MRA_BANK5:
  1435.     case (FPTR)MRA_BANK6:
  1436.     case (FPTR)MRA_BANK7:
  1437.     case (FPTR)MRA_BANK8:
  1438.     case (FPTR)MRA_BANK9:
  1439.     case (FPTR)MRA_BANK10:
  1440.     case (FPTR)MRA_BANK11:
  1441.     case (FPTR)MRA_BANK12:
  1442.     case (FPTR)MRA_BANK13:
  1443.     case (FPTR)MRA_BANK14:
  1444.     case (FPTR)MRA_BANK15:
  1445.     case (FPTR)MRA_BANK16:
  1446.         hardware = (int)MWA_BANK1 - (int)handler + 1;
  1447.         handler = bank_read_handler[hardware];
  1448.         offset = bankreadoffset[hardware];
  1449.         break;
  1450.     case (FPTR)MRA_NOP:
  1451.         handler = mrh_nop;
  1452.         break;
  1453.     default:
  1454.         offset = bankreadoffset[bank];
  1455.         break;
  1456.     }
  1457.     memoryreadoffset[bank] = offset;
  1458.     memoryreadhandler[bank] = handler;
  1459. }
  1460.  
  1461. /* set writememory handler for bank memory    */
  1462. void cpu_setbankhandler_w(int bank, mem_write_handler handler)
  1463. {
  1464.     int offset = 0;
  1465.     MHELE hardware;
  1466.  
  1467.     switch( (FPTR)handler )
  1468.     {
  1469.     case (FPTR)MWA_RAM:
  1470.         handler = mwh_ram;
  1471.         break;
  1472.     case (FPTR)MWA_BANK1:
  1473.     case (FPTR)MWA_BANK2:
  1474.     case (FPTR)MWA_BANK3:
  1475.     case (FPTR)MWA_BANK4:
  1476.     case (FPTR)MWA_BANK5:
  1477.     case (FPTR)MWA_BANK6:
  1478.     case (FPTR)MWA_BANK7:
  1479.     case (FPTR)MWA_BANK8:
  1480.     case (FPTR)MWA_BANK9:
  1481.     case (FPTR)MWA_BANK10:
  1482.     case (FPTR)MWA_BANK11:
  1483.     case (FPTR)MWA_BANK12:
  1484.     case (FPTR)MWA_BANK13:
  1485.     case (FPTR)MWA_BANK14:
  1486.     case (FPTR)MWA_BANK15:
  1487.     case (FPTR)MWA_BANK16:
  1488.         hardware = (int)MWA_BANK1 - (int)handler + 1;
  1489.         handler = bank_write_handler[hardware];
  1490.         offset = bankwriteoffset[hardware];
  1491.         break;
  1492.     case (FPTR)MWA_NOP:
  1493.         handler = mwh_nop;
  1494.         break;
  1495.     case (FPTR)MWA_RAMROM:
  1496.         handler = mwh_ramrom;
  1497.         break;
  1498.     case (FPTR)MWA_ROM:
  1499.         handler = mwh_rom;
  1500.         break;
  1501.     default:
  1502.         offset = bankwriteoffset[bank];
  1503.         break;
  1504.     }
  1505.     memorywriteoffset[bank] = offset;
  1506.     memorywritehandler[bank] = handler;
  1507. }
  1508.  
  1509. /* cpu change op-code memory base */
  1510. void cpu_setOPbaseoverride (int cpu,opbase_handler function)
  1511. {
  1512.     setOPbasefunc[cpu] = function;
  1513.     if (cpu == cpu_getactivecpu())
  1514.         OPbasefunc = function;
  1515. }
  1516.  
  1517.  
  1518. void *install_mem_read_handler(int cpu, int start, int end, mem_read_handler handler)
  1519. {
  1520.     MHELE hardware = 0;
  1521.     int abitsmin;
  1522.     int i, hw_set;
  1523.     logerror("Install new memory read handler:\n");
  1524.     logerror("             cpu: %d\n", cpu);
  1525.     logerror("           start: 0x%08x\n", start);
  1526.     logerror("             end: 0x%08x\n", end);
  1527. #ifdef __LP64__
  1528.     logerror(" handler address: 0x%016lx\n", (unsigned long) handler);
  1529. #else
  1530.     logerror(" handler address: 0x%08x\n", (unsigned int) handler);
  1531. #endif
  1532.     abitsmin = ABITSMIN (cpu);
  1533.  
  1534.     /* see if this function is already registered */
  1535.     hw_set = 0;
  1536.     for ( i = 0 ; i < MH_HARDMAX ; i++)
  1537.     {
  1538.         /* record it if it matches */
  1539.         if (( memoryreadhandler[i] == handler ) &&
  1540.             (  memoryreadoffset[i] == start))
  1541.         {
  1542.             logerror("handler match - use old one\n");
  1543.             hardware = i;
  1544.             hw_set = 1;
  1545.         }
  1546.     }
  1547.     switch ((FPTR)handler)
  1548.     {
  1549.         case (FPTR)MRA_RAM:
  1550.         case (FPTR)MRA_ROM:
  1551.             hardware = HT_RAM;    /* sprcial case ram read */
  1552.             hw_set = 1;
  1553.             break;
  1554.         case (FPTR)MRA_BANK1:
  1555.         case (FPTR)MRA_BANK2:
  1556.         case (FPTR)MRA_BANK3:
  1557.         case (FPTR)MRA_BANK4:
  1558.         case (FPTR)MRA_BANK5:
  1559.         case (FPTR)MRA_BANK6:
  1560.         case (FPTR)MRA_BANK7:
  1561.         case (FPTR)MRA_BANK8:
  1562.         case (FPTR)MRA_BANK9:
  1563.         case (FPTR)MRA_BANK10:
  1564.         case (FPTR)MRA_BANK11:
  1565.         case (FPTR)MRA_BANK12:
  1566.         case (FPTR)MRA_BANK13:
  1567.         case (FPTR)MRA_BANK14:
  1568.         case (FPTR)MRA_BANK15:
  1569.         case (FPTR)MRA_BANK16:
  1570.         {
  1571.             hardware = (int)MRA_BANK1 - (int)handler + 1;
  1572.             hw_set = 1;
  1573.             break;
  1574.         }
  1575.         case (FPTR)MRA_NOP:
  1576.             hardware = HT_NOP;
  1577.             hw_set = 1;
  1578.             break;
  1579.     }
  1580.     if (!hw_set)  /* no match */
  1581.     {
  1582.         /* create newer hardware handler */
  1583.         if( rdhard_max == MH_HARDMAX )
  1584.         {
  1585.             logerror("read memory hardware pattern over !\n");
  1586.             logerror("Failed to install new memory handler.\n");
  1587.             return memory_find_base(cpu, start);
  1588.         }
  1589.         else
  1590.         {
  1591.             /* register hardware function */
  1592.             hardware = rdhard_max++;
  1593.             memoryreadhandler[hardware] = handler;
  1594.             memoryreadoffset[hardware] = start;
  1595.         }
  1596.     }
  1597.     /* set hardware element table entry */
  1598.     set_element( cpu , cur_mr_element[cpu] ,
  1599.         (((unsigned int) start) >> abitsmin) ,
  1600.         (((unsigned int) end) >> abitsmin) ,
  1601.         hardware , readhardware , &rdelement_max );
  1602.     logerror("Done installing new memory handler.\n");
  1603.     logerror("used read  elements %d/%d , functions %d/%d\n"
  1604.             ,rdelement_max,MH_ELEMAX , rdhard_max,MH_HARDMAX );
  1605.     return memory_find_base(cpu, start);
  1606. }
  1607.  
  1608. void *install_mem_write_handler(int cpu, int start, int end, mem_write_handler handler)
  1609. {
  1610.     MHELE hardware = 0;
  1611.     int abitsmin;
  1612.     int i, hw_set;
  1613.     logerror("Install new memory write handler:\n");
  1614.     logerror("             cpu: %d\n", cpu);
  1615.     logerror("           start: 0x%08x\n", start);
  1616.     logerror("             end: 0x%08x\n", end);
  1617. #ifdef __LP64__
  1618.     logerror(" handler address: 0x%016lx\n", (unsigned long) handler);
  1619. #else
  1620.     logerror(" handler address: 0x%08x\n", (unsigned int) handler);
  1621. #endif
  1622.     abitsmin = ABITSMIN (cpu);
  1623.  
  1624.     /* see if this function is already registered */
  1625.     hw_set = 0;
  1626.     for ( i = 0 ; i < MH_HARDMAX ; i++)
  1627.     {
  1628.         /* record it if it matches */
  1629.         if (( memorywritehandler[i] == handler ) &&
  1630.             (  memorywriteoffset[i] == start))
  1631.         {
  1632.             logerror("handler match - use old one\n");
  1633.             hardware = i;
  1634.             hw_set = 1;
  1635.         }
  1636.     }
  1637.  
  1638.     switch( (FPTR)handler )
  1639.     {
  1640.         case (FPTR)MWA_RAM:
  1641.             hardware = HT_RAM;    /* sprcial case ram write */
  1642.             hw_set = 1;
  1643.             break;
  1644.         case (FPTR)MWA_BANK1:
  1645.         case (FPTR)MWA_BANK2:
  1646.         case (FPTR)MWA_BANK3:
  1647.         case (FPTR)MWA_BANK4:
  1648.         case (FPTR)MWA_BANK5:
  1649.         case (FPTR)MWA_BANK6:
  1650.         case (FPTR)MWA_BANK7:
  1651.         case (FPTR)MWA_BANK8:
  1652.         case (FPTR)MWA_BANK9:
  1653.         case (FPTR)MWA_BANK10:
  1654.         case (FPTR)MWA_BANK11:
  1655.         case (FPTR)MWA_BANK12:
  1656.         case (FPTR)MWA_BANK13:
  1657.         case (FPTR)MWA_BANK14:
  1658.         case (FPTR)MWA_BANK15:
  1659.         case (FPTR)MWA_BANK16:
  1660.         {
  1661.             hardware = (int)MWA_BANK1 - (int)handler + 1;
  1662.             hw_set = 1;
  1663.             break;
  1664.         }
  1665.         case (FPTR)MWA_NOP:
  1666.             hardware = HT_NOP;
  1667.             hw_set = 1;
  1668.             break;
  1669.         case (FPTR)MWA_RAMROM:
  1670.             hardware = HT_RAMROM;
  1671.             hw_set = 1;
  1672.             break;
  1673.         case (FPTR)MWA_ROM:
  1674.             hardware = HT_ROM;
  1675.             hw_set = 1;
  1676.             break;
  1677.     }
  1678.     if (!hw_set)  /* no match */
  1679.     {
  1680.         /* create newer hardware handler */
  1681.         if( wrhard_max == MH_HARDMAX )
  1682.         {
  1683.             logerror("write memory hardware pattern over !\n");
  1684.             logerror("Failed to install new memory handler.\n");
  1685.  
  1686.             return memory_find_base(cpu, start);
  1687.         }
  1688.         else
  1689.         {
  1690.             /* register hardware function */
  1691.             hardware = wrhard_max++;
  1692.             memorywritehandler[hardware] = handler;
  1693.             memorywriteoffset[hardware] = start;
  1694.         }
  1695.     }
  1696.     /* set hardware element table entry */
  1697.     set_element( cpu , cur_mw_element[cpu] ,
  1698.         (((unsigned int) start) >> abitsmin) ,
  1699.         (((unsigned int) end) >> abitsmin) ,
  1700.         hardware , writehardware , &wrelement_max );
  1701.     logerror("Done installing new memory handler.\n");
  1702.     logerror("used write elements %d/%d , functions %d/%d\n"
  1703.             ,wrelement_max,MH_ELEMAX , wrhard_max,MH_HARDMAX );
  1704.     return memory_find_base(cpu, start);
  1705. }
  1706.  
  1707. void *install_port_read_handler(int cpu, int start, int end, mem_read_handler handler)
  1708. {
  1709.     return install_port_read_handler_common(cpu, start, end, handler, 1);
  1710. }
  1711.  
  1712. void *install_port_write_handler(int cpu, int start, int end, mem_write_handler handler)
  1713. {
  1714.     return install_port_write_handler_common(cpu, start, end, handler, 1);
  1715. }
  1716.  
  1717. static void *install_port_read_handler_common(int cpu, int start, int end,
  1718.                                               mem_read_handler handler, int install_at_beginning)
  1719. {
  1720.     int i, oldsize;
  1721.  
  1722.     oldsize = readport_size[cpu];
  1723.     readport_size[cpu] += sizeof(struct IOReadPort);
  1724.  
  1725.     if (readport[cpu] == 0)
  1726.     {
  1727.         readport[cpu] = malloc(readport_size[cpu]);
  1728.     }
  1729.     else
  1730.     {
  1731.         readport[cpu] = realloc(readport[cpu], readport_size[cpu]);
  1732.     }
  1733.  
  1734.     if (readport[cpu] == 0)  return 0;
  1735.  
  1736.     if (install_at_beginning)
  1737.     {
  1738.         /* can't do a single memcpy because it doesn't handle overlapping regions correctly??? */
  1739.         for (i = oldsize / sizeof(struct IOReadPort); i >= 1; i--)
  1740.         {
  1741.             memcpy(&readport[cpu][i], &readport[cpu][i - 1], sizeof(struct IOReadPort));
  1742.         }
  1743.  
  1744.         i = 0;
  1745.     }
  1746.     else
  1747.     {
  1748.         i = oldsize / sizeof(struct IOReadPort);
  1749.     }
  1750.  
  1751. #ifdef MEM_DUMP
  1752.     logerror("Installing port read handler: cpu %d  slot %X  start %X  end %X\n", cpu, i, start, end);
  1753. #endif
  1754.  
  1755.     readport[cpu][i].start = start;
  1756.     readport[cpu][i].end = end;
  1757.     readport[cpu][i].handler = handler;
  1758.  
  1759.     return readport[cpu];
  1760. }
  1761.  
  1762. static void *install_port_write_handler_common(int cpu, int start, int end,
  1763.                                                mem_write_handler handler, int install_at_beginning)
  1764. {
  1765.     int i, oldsize;
  1766.  
  1767.     oldsize = writeport_size[cpu];
  1768.     writeport_size[cpu] += sizeof(struct IOWritePort);
  1769.  
  1770.     if (writeport[cpu] == 0)
  1771.     {
  1772.         writeport[cpu] = malloc(writeport_size[cpu]);
  1773.     }
  1774.     else
  1775.     {
  1776.         writeport[cpu] = realloc(writeport[cpu], writeport_size[cpu]);
  1777.     }
  1778.  
  1779.     if (writeport[cpu] == 0)  return 0;
  1780.  
  1781.     if (install_at_beginning)
  1782.     {
  1783.         /* can't do a single memcpy because it doesn't handle overlapping regions correctly??? */
  1784.         for (i = oldsize / sizeof(struct IOWritePort); i >= 1; i--)
  1785.         {
  1786.             memcpy(&writeport[cpu][i], &writeport[cpu][i - 1], sizeof(struct IOWritePort));
  1787.         }
  1788.  
  1789.         i = 0;
  1790.     }
  1791.     else
  1792.     {
  1793.         i = oldsize / sizeof(struct IOWritePort);
  1794.     }
  1795.  
  1796. #ifdef MEM_DUMP
  1797.     logerror("Installing port write handler: cpu %d  slot %X  start %X  end %X\n", cpu, i, start, end);
  1798. #endif
  1799.  
  1800.     writeport[cpu][i].start = start;
  1801.     writeport[cpu][i].end = end;
  1802.     writeport[cpu][i].handler = handler;
  1803.  
  1804.     return writeport[cpu];
  1805. }
  1806.  
  1807. #ifdef MEM_DUMP
  1808. static void mem_dump( void )
  1809. {
  1810.     extern int totalcpu;
  1811.     int cpu;
  1812.     int naddr,addr;
  1813.     MHELE nhw,hw;
  1814.  
  1815.     FILE *temp = fopen ("memdump.log", "w");
  1816.  
  1817.     if (!temp) return;
  1818.  
  1819.     for( cpu = 0 ; cpu < 1 ; cpu++ )
  1820.     {
  1821.         fprintf(temp,"cpu %d read memory \n",cpu);
  1822.         addr = 0;
  1823.         naddr = 0;
  1824.         nhw = 0xff;
  1825.         while( (addr >> mhshift[cpu][0]) <= mhmask[cpu][0] ){
  1826.             hw = cur_mr_element[cpu][addr >> mhshift[cpu][0]];
  1827.             if( hw >= MH_HARDMAX )
  1828.             {    /* 2nd element link */
  1829.                 hw = readhardware[((hw-MH_HARDMAX)<<MH_SBITS) + ((addr>>mhshift[cpu][1]) & mhmask[cpu][1])];
  1830.                 if( hw >= MH_HARDMAX )
  1831.                     hw = readhardware[((hw-MH_HARDMAX)<<MH_SBITS) + (addr & mhmask[cpu][2])];
  1832.             }
  1833.             if( nhw != hw )
  1834.             {
  1835.                 if( addr )
  1836.     fprintf(temp,"  %08x(%08x) - %08x = %02x\n",naddr,memoryreadoffset[nhw],addr-1,nhw);
  1837.                 nhw = hw;
  1838.                 naddr = addr;
  1839.             }
  1840.             addr++;
  1841.         }
  1842.         fprintf(temp,"  %08x(%08x) - %08x = %02x\n",naddr,memoryreadoffset[nhw],addr-1,nhw);
  1843.  
  1844.         fprintf(temp,"cpu %d write memory \n",cpu);
  1845.         naddr = 0;
  1846.         addr = 0;
  1847.         nhw = 0xff;
  1848.         while( (addr >> mhshift[cpu][0]) <= mhmask[cpu][0] ){
  1849.             hw = cur_mw_element[cpu][addr >> mhshift[cpu][0]];
  1850.             if( hw >= MH_HARDMAX )
  1851.             {    /* 2nd element link */
  1852.                 hw = writehardware[((hw-MH_HARDMAX)<<MH_SBITS) + ((addr>>mhshift[cpu][1]) & mhmask[cpu][1])];
  1853.                 if( hw >= MH_HARDMAX )
  1854.                     hw = writehardware[((hw-MH_HARDMAX)<<MH_SBITS) + (addr & mhmask[cpu][2])];
  1855.             }
  1856.             if( nhw != hw )
  1857.             {
  1858.                 if( addr )
  1859.     fprintf(temp,"  %08x(%08x) - %08x = %02x\n",naddr,memorywriteoffset[nhw],addr-1,nhw);
  1860.                 nhw = hw;
  1861.                 naddr = addr;
  1862.             }
  1863.             addr++;
  1864.         }
  1865.     fprintf(temp,"  %08x(%08x) - %08x = %02x\n",naddr,memorywriteoffset[nhw],addr-1,nhw);
  1866.     }
  1867.     fclose(temp);
  1868. }
  1869. #endif
  1870.  
  1871.